

<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  
  <title>测试 - 单元测试 &mdash; Ceph Documentation</title>
  

  
  <link rel="stylesheet" href="../../../_static/ceph.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/ceph.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/graphviz.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/css/custom.css" type="text/css" />

  
  

  
  

  

  
  <!--[if lt IE 9]>
    <script src="../../../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
        <script src="../../../_static/jquery.js"></script>
        <script src="../../../_static/_sphinx_javascript_frameworks_compat.js"></script>
        <script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
        <script src="../../../_static/doctools.js"></script>
        <script src="../../../_static/sphinx_highlight.js"></script>
    
    <script type="text/javascript" src="../../../_static/js/theme.js"></script>

    
    <link rel="index" title="Index" href="../../../genindex/" />
    <link rel="search" title="Search" href="../../../search/" />
    <link rel="next" title="Teuthology 用户指南" href="../testing_integration_tests/" />
    <link rel="prev" title="Basic Workflow" href="../basic-workflow/" /> 
</head>

<body class="wy-body-for-nav">

   
  <header class="top-bar">
    <div role="navigation" aria-label="Page navigation">
  <ul class="wy-breadcrumbs">
      <li><a href="../../../" class="icon icon-home" aria-label="Home"></a></li>
          <li class="breadcrumb-item"><a href="../">向 Ceph 贡献：开发者指南</a></li>
      <li class="breadcrumb-item active">测试 - 单元测试</li>
      <li class="wy-breadcrumbs-aside">
            <a href="../../../_sources/dev/developer_guide/tests-unit-tests.rst.txt" rel="nofollow"> View page source</a>
      </li>
  </ul>
  <hr/>
</div>
  </header>
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search"  style="background: #eee" >
          

          
            <a href="../../../" class="icon icon-home"> Ceph
          

          
          </a>

          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../../search/" method="get">
    <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../../start/">Ceph 简介</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../install/">安装 Ceph</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../cephadm/">Cephadm</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../rados/">Ceph 存储集群</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../cephfs/">Ceph 文件系统</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../rbd/">Ceph 块设备</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../radosgw/">Ceph 对象网关</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mgr/">Ceph 管理器守护进程</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mgr/dashboard/">Ceph 仪表盘</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../monitoring/">监控概览</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../api/">API 文档</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../architecture/">体系结构</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../">开发者指南</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../intro/">简介</a></li>
<li class="toctree-l2"><a class="reference internal" href="../essentials/">必备知识</a></li>
<li class="toctree-l2"><a class="reference internal" href="../merging/">何时、合并了什么</a></li>
<li class="toctree-l2"><a class="reference internal" href="../issue-tracker/">问题追踪器</a></li>
<li class="toctree-l2"><a class="reference internal" href="../basic-workflow/">基本工作流</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">测试：单元测试</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#what-does-make-check-mean">What does “make check” mean?</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#id2">如何声明单元测试</a></li>
<li class="toctree-l4"><a class="reference internal" href="#cli">CLI 工具的单元测试</a></li>
<li class="toctree-l4"><a class="reference internal" href="#tox-based-testing-of-python-modules">Tox based testing of python modules</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#id3">单元测试注意事项</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../testing_integration_tests/">测试：集成测试(Teuthology)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../running-tests-locally/">测试：在本地运行测试</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tests-windows/">测试: Windows</a></li>
<li class="toctree-l2"><a class="reference internal" href="../dash-devel/">Ceph Dashboard 开发者文档 (之前是 HACKING.rst)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../jaegertracing/">Tracing 开发者文档</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../cephadm/">Cephadm 开发者文档</a></li>
<li class="toctree-l2"><a class="reference internal" href="../debugging-gdb/">用 GDB 调试</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../internals/">Ceph 内幕</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../governance/">项目管理</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../foundation/">Ceph 基金会</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../ceph-volume/">ceph-volume</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../releases/general/">Ceph 版本（总目录）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../releases/">Ceph 版本（索引）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../security/">Security</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../hardware-monitoring/">硬件监控</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../glossary/">Ceph 术语</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../jaegertracing/">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../translation_cn/">中文版翻译资源</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../../../">Ceph</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
<div id="dev-warning" class="admonition note">
  <p class="first admonition-title">Notice</p>
  <p class="last">This document is for a development version of Ceph.</p>
</div>
  <div id="docubetter" align="right" style="padding: 5px; font-weight: bold;">
    <a href="https://pad.ceph.com/p/Report_Documentation_Bugs">Report a Documentation Bug</a>
  </div>

  
  <section id="dev-testing-unit-tests">
<span id="id1"></span><h1>测试 - 单元测试<a class="headerlink" href="#dev-testing-unit-tests" title="Permalink to this heading"></a></h1>
<p>The Ceph GitHub repository has two types of tests: unit tests (also called
<code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">check</span></code> tests) and integration tests. Strictly speaking, the
<code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">check</span></code> tests are not “unit tests”, but rather tests that can be run
easily on a single build machine after compiling Ceph from source, whereas
integration tests require package installation and multi-machine clusters to
run.</p>
<section id="what-does-make-check-mean">
<span id="make-check"></span><h2>What does “make check” mean?<a class="headerlink" href="#what-does-make-check-mean" title="Permalink to this heading"></a></h2>
<p>After compiling Ceph, the code can be run through a battery of tests. For
historical reasons, this is often referred to as <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">check</span></code> even though
the actual command used to run the tests is now <code class="docutils literal notranslate"><span class="pre">ctest</span></code>. To be included in
this group of tests, a test must:</p>
<ul class="simple">
<li><p>bind ports that do not conflict with other tests</p></li>
<li><p>not require root access</p></li>
<li><p>not require more than one machine to run</p></li>
<li><p>complete within a few minutes</p></li>
</ul>
<p>For the sake of simplicity, this class of tests is referred to as “make
check tests” or “unit tests”. This is meant to distinguish these tests from
the more complex “integration tests” that are run via the <a class="reference external" href="https://github.com/ceph/teuthology">teuthology
framework</a>.</p>
<p>While it is possible to run <code class="docutils literal notranslate"><span class="pre">ctest</span></code> directly, it can be tricky to correctly
set up your environment for it. Fortunately, there is a script that makes it
easy to run the unit tests on your code. This script can be run from the
top-level directory of the Ceph source tree by invoking:</p>
<blockquote>
<div><div class="highlight-default notranslate"><div class="highlight"><pre><style type="text/css">
span.prompt1:before {
  content: "$ ";
}
</style><span class="prompt1">./run-make-check.sh</span>
</pre></div></div></div></blockquote>
<p>You will need a minimum of 8GB of RAM and 32GB of free drive space for this
command to complete successfully on x86_64 architectures; other architectures
may have different requirements. Depending on your hardware, it can take from
twenty minutes to three hours to complete.</p>
<section id="id2">
<h3>如何声明单元测试<a class="headerlink" href="#id2" title="Permalink to this heading"></a></h3>
<p>Unit tests are declared in the <code class="docutils literal notranslate"><span class="pre">CMakeLists.txt</span></code> file, which is found in the
<code class="docutils literal notranslate"><span class="pre">./src</span></code> directory. The <code class="docutils literal notranslate"><span class="pre">add_ceph_test</span></code> and <code class="docutils literal notranslate"><span class="pre">add_ceph_unittest</span></code> CMake
functions are used to declare unit tests.  <code class="docutils literal notranslate"><span class="pre">add_ceph_test</span></code> and
<code class="docutils literal notranslate"><span class="pre">add_ceph_unittest</span></code> are themselves defined in
<code class="docutils literal notranslate"><span class="pre">./cmake/modules/AddCephTest.cmake</span></code>.</p>
<p>Some unit tests are scripts and other unit tests are binaries that are
compiled during the build process.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">add_ceph_test</span></code> function - used to declare unit test scripts</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">add_ceph_unittest</span></code> function - used for unit test binaries</p></li>
</ul>
</section>
<section id="cli">
<h3>CLI 工具的单元测试<a class="headerlink" href="#cli" title="Permalink to this heading"></a></h3>
<p>Some of the CLI tools are tested using special files ending with the extension
<code class="docutils literal notranslate"><span class="pre">.t</span></code> and stored under <code class="docutils literal notranslate"><span class="pre">./src/test/cli</span></code>. These tests are run using a tool
called <a class="reference external" href="https://bitheap.org/cram/">cram</a> via a shell script called <code class="docutils literal notranslate"><span class="pre">./src/test/run-cli-tests</span></code>.
<a class="reference external" href="https://bitheap.org/cram/">cram</a> tests that are not suitable for <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">check</span></code> can also be run by
teuthology using the <a class="reference external" href="https://github.com/ceph/ceph/blob/master/qa/tasks/cram.py">cram task</a>.</p>
</section>
<section id="tox-based-testing-of-python-modules">
<h3>Tox based testing of python modules<a class="headerlink" href="#tox-based-testing-of-python-modules" title="Permalink to this heading"></a></h3>
<p>Some of the Python modules in Ceph use <a class="reference external" href="https://tox.readthedocs.io/en/latest/">tox</a>
to run their unit tests.</p>
<p>Most of these Python modules can be found in the directory <code class="docutils literal notranslate"><span class="pre">./src/pybind/</span></code>.</p>
<p>Currently (December 2020) the following modules use <strong>tox</strong>:</p>
<ul class="simple">
<li><p>Cephadm (<code class="docutils literal notranslate"><span class="pre">./src/cephadm/tox.ini</span></code>)</p></li>
<li><p>Ceph Manager Python API (<code class="docutils literal notranslate"><span class="pre">./src/pybind/mgr</span></code>)</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">./src/pybind/mgr/tox.ini</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">./src/pybind/mgr/dashboard/tox.ini</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">./src/pybind/tox.ini</span></code></p></li>
</ul>
</li>
<li><p>Dashboard (<code class="docutils literal notranslate"><span class="pre">./src/pybind/mgr/dashboard</span></code>)</p></li>
<li><p>Python common (<code class="docutils literal notranslate"><span class="pre">./src/python-common/tox.ini</span></code>)</p></li>
<li><p>CephFS (<code class="docutils literal notranslate"><span class="pre">./src/tools/cephfs/tox.ini</span></code>)</p></li>
<li><p>ceph-volume</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">./src/ceph-volume/tox.ini</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">./src/ceph-volume/plugin/zfs/tox.ini</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">./src/ceph-volume/ceph_volume/tests/functional/batch/tox.ini</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">./src/ceph-volume/ceph_volume/tests/functional/simple/tox.ini</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">./src/ceph-volume/ceph_volume/tests/functional/lvm/tox.ini</span></code></p></li>
</ul>
</li>
</ul>
<section id="configuring-tox-environments-and-tasks">
<h4>Configuring Tox environments and tasks<a class="headerlink" href="#configuring-tox-environments-and-tasks" title="Permalink to this heading"></a></h4>
<p>Most tox configurations support multiple environments and tasks.</p>
<p>The list of environments and tasks that are supported is in the <code class="docutils literal notranslate"><span class="pre">tox.ini</span></code>
file, under <code class="docutils literal notranslate"><span class="pre">envlist</span></code>. For example, here are the first three lines of
<code class="docutils literal notranslate"><span class="pre">./src/cephadm/tox.ini</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">tox</span><span class="p">]</span>
<span class="n">envlist</span> <span class="o">=</span> <span class="n">py3</span><span class="p">,</span> <span class="n">mypy</span>
<span class="n">skipsdist</span><span class="o">=</span><span class="n">true</span>
</pre></div>
</div>
<p>In this example, the <code class="docutils literal notranslate"><span class="pre">Python</span> <span class="pre">3</span></code> and <code class="docutils literal notranslate"><span class="pre">mypy</span></code> environments are specified.</p>
<p>The list of environments can be retrieved with the following command:</p>
<blockquote>
<div><div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">tox<span class="w"> </span>--list</span>
</pre></div></div></div></blockquote>
<p>Or:</p>
<blockquote>
<div><div class="highlight-default notranslate"><div class="highlight"><pre><span class="prompt1">tox<span class="w"> </span>-l</span>
</pre></div></div></div></blockquote>
</section>
<section id="running-tox">
<h4>Running Tox<a class="headerlink" href="#running-tox" title="Permalink to this heading"></a></h4>
<p>To run <strong>tox</strong>, just execute <code class="docutils literal notranslate"><span class="pre">tox</span></code> in the directory containing
<code class="docutils literal notranslate"><span class="pre">tox.ini</span></code>.  If you do not specify any environments (for example, <code class="docutils literal notranslate"><span class="pre">-e</span>
<span class="pre">$env1,$env2</span></code>), then <code class="docutils literal notranslate"><span class="pre">tox</span></code> will run all environments. Jenkins will run
<code class="docutils literal notranslate"><span class="pre">tox</span></code> by executing <code class="docutils literal notranslate"><span class="pre">./src/script/run_tox.sh</span></code>.</p>
<p>Here are some examples from Ceph Dashboard that show how to specify different
environments and run options:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>## Run Python 2+3 tests+lint commands:
$ tox -e py27,py3,lint,check

## Run Python 3 tests+lint commands:
$ tox -e py3,lint,check

## To run it as Jenkins would:
$ ../../../script/run_tox.sh --tox-env py3,lint,check
</pre></div>
</div>
</section>
<section id="manager-core-unit-tests">
<h4>Manager core unit tests<a class="headerlink" href="#manager-core-unit-tests" title="Permalink to this heading"></a></h4>
<p>Currently only <a class="reference external" href="https://docs.python.org/3/library/doctest.html">doctests</a> inside <code class="docutils literal notranslate"><span class="pre">mgr_util.py</span></code> are run.</p>
<p>To add more files to be tested inside the core of the manager, open the
<code class="docutils literal notranslate"><span class="pre">tox.ini</span></code> file and add the files to be tested  at the end of the line that
includes <code class="docutils literal notranslate"><span class="pre">mgr_util.py</span></code>.</p>
</section>
</section>
</section>
<section id="id3">
<h2>单元测试注意事项<a class="headerlink" href="#id3" title="Permalink to this heading"></a></h2>
<ol class="arabic simple">
<li><p>Unlike the various Ceph daemons and <code class="docutils literal notranslate"><span class="pre">ceph-fuse</span></code>, the unit tests are
linked against the default memory allocator (glibc) unless they are
explicitly linked against something else. This enables tools such as
<strong>valgrind</strong> to be used in the tests.</p></li>
<li><p>Google Test unit testing library hides the client output from the shell.
In order to debug the client after setting the desired debug level
(e.g <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">config</span> <span class="pre">set</span> <span class="pre">client</span> <span class="pre">debug_rbd</span> <span class="pre">20</span></code>), the debug log file can
be found at <code class="docutils literal notranslate"><span class="pre">build/out/client.admin.&lt;pid&gt;.log</span></code>.
This can also be handy when examining teuthology failed unit test
jobs, the job’s debug level can be set at the relevant yaml file.</p></li>
</ol>
</section>
</section>



<div id="support-the-ceph-foundation" class="admonition note">
  <p class="first admonition-title">Brought to you by the Ceph Foundation</p>
  <p class="last">The Ceph Documentation is a community resource funded and hosted by the non-profit <a href="https://ceph.io/en/foundation/">Ceph Foundation</a>. If you would like to support this and our other efforts, please consider <a href="https://ceph.io/en/foundation/join/">joining now</a>.</p>
</div>


           </div>
           
          </div>
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
        <a href="../basic-workflow/" class="btn btn-neutral float-left" title="Basic Workflow" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
        <a href="../testing_integration_tests/" class="btn btn-neutral float-right" title="Teuthology 用户指南" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>&#169; Copyright 2016, Ceph authors and contributors. Licensed under Creative Commons Attribution Share Alike 3.0 (CC-BY-SA-3.0).</p>
  </div>

   

</footer>
        </div>
      </div>

    </section>

  </div>
  

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
   

</body>
</html>